package com.example.learn01.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.learn01.common.Result;
import com.example.learn01.entity.Files;
import com.example.learn01.mapper.FileMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.json.JsonParser;
import org.springframework.boot.json.JsonParserFactory;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

import com.example.learn01.service.IFileService;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author baomidou
 * @since 2024-05-06
 */
@RestController
@RequestMapping("/file")
public class FileController {
        //实现依赖注入
        @Resource
        private IFileService fileService;

        @Resource
        private FileMapper fileMapper;

        //引入存储文件的路径并赋值
       @Value("${files.upload.path}")
       private String fileUploadPath;

        //上传文件
        @PostMapping("upload")
            public Result upload(@RequestParam MultipartFile file )throws IOException {
                //获取文件名称
                String originnalFilename=file.getOriginalFilename();
                //获取文件类型
                String type = FileUtil.extName(originnalFilename);
                //获取文件大小
                long size = file.getSize();
                //存储文件到磁盘
                File uploadParentFile=new File(fileUploadPath);
                //判断文件目录是否存在,不存在则创建
                if (!uploadParentFile.exists()){
                    uploadParentFile.mkdirs();
                }
                //定义一个文件名称唯一标识
                String uuid= IdUtil.fastSimpleUUID();
                String fileUuid=uuid+ StrUtil.DOT+type;
                File uploadFil=new File(fileUploadPath +fileUuid); //存储路径要加上fileUploadPath（磁盘具体路径）

                //获取文件md5
                //把获取的文件存储到磁盘目录，只有存到磁盘才能获取文件md5
                file.transferTo(uploadFil);
                String md5= SecureUtil.md5(uploadFil);
                Files files=getFileByMd5(md5);
                String url;
                if(files!=null){
                    //取存在的url
                     url=files.getUrl();
                     //删除上传的文件
                    uploadFil.delete();
                }else {
                    url="http://localhost:9090/file/"+fileUuid; //访问路径通过域名
                }


                //存储数据库
                Files saveFile=new Files();
                saveFile.setName(originnalFilename);
                saveFile.setType(type);
                saveFile.setSize(size/1024); //除1024转kb
                saveFile.setUrl(url);
                saveFile.setMd5(md5);
                fileService.saveOrUpdate(saveFile);

                //返回结果
                Result res= new Result();
                return res.success("success",saveFile);
            }
        //下载文件
        @GetMapping("/{fileUUID}")
        public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {//根据文件的唯一标识码获取文件
            File uploadFile = new File( fileUploadPath + fileUUID);
            // 设置输出流的格式
            ServletOutputStream os = response.getOutputStream();
            response.addHeader( "Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID,"UTF-8"));
            response.setContentType("application/octet-stream");
            // 读取文件的字节流
            os.write(FileUtil.readBytes(uploadFile));
            os.flush();
            os.close();
        }

        private  Files getFileByMd5(String md5){
            QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("md5",md5);
            List<Files> filesList=fileMapper.selectList(queryWrapper);
            return filesList.size()==0?null:filesList.get(0);
        }



       //新增或更新
        @PostMapping("/saveOrUpdate")
        public Boolean save(@RequestBody Files file) {
            return fileService.saveOrUpdate(file);
        }
//        //删除
//        @DeleteMapping("/{id}")
//        public Boolean delete(@PathVariable Integer id) {
//            return fileService.removeById(id);
//        }
//        //查询
//        @GetMapping
//        public List<File> findAll() {
//            return fileService.list();
//        }
        //根据id查询
        @PostMapping("/getById")
        public Files findOne(@RequestBody String jsonData) {
            JsonParser jsonParser = JsonParserFactory.getJsonParser();
            Map<String, Object> jsonMap = jsonParser.parseMap(jsonData);
            Integer id = (Integer) jsonMap.get("id");
            return fileService.getById(id);
        }
        //分页查询
        @PostMapping("/page")
        public Page<Files> findPage(@RequestBody String jsonData) {
            // 手动解析JSON数据为Map对象
            JsonParser jsonParser = JsonParserFactory.getJsonParser();
            Map<String, Object> jsonMap = jsonParser.parseMap(jsonData);
            Integer pageNum = (Integer) jsonMap.get("pageNum");
            Integer pageSize = (Integer) jsonMap.get("pageSize");
            //设置查询isDelete等于true的数据
            QueryWrapper<Files> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("is_delete",true);
            return fileService.page(new Page<>(pageNum, pageSize),queryWrapper);
        }

}
